package org.alesv.entranceExams.web.taglib;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * Utilidades comunes a los tags.
 */
public final class Utils {

    /**
     * Carga una clase del contexto.
     * 
     * @param className
     *            Nombre de la clase.
     * @return Clase del contexto.
     * @throws ClassNotFoundException
     *             Si ocurre un error.
     */
    @SuppressWarnings("unchecked")
    public static Class loadClass(final String className) throws ClassNotFoundException {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        if (classLoader == null) {
            classLoader = ConstantsTag.class.getClassLoader();
        }
        return classLoader.loadClass(className);
    }

    /**
     * Crea una nueva instancia de una clase.
     * 
     * @param className
     *            Nombre de la clase.
     * @return Instancia de la clase.
     * @throws ClassNotFoundException
     *             Si ocurre un error.
     * @throws IllegalAccessException
     *             Si ocurre un error.
     * @throws InstantiationException
     *             Si ocurre un error.
     */
    public static Object createInstance(final String className) throws ClassNotFoundException, IllegalAccessException,
        InstantiationException {
        return loadClass(className).newInstance();
    }

    /**
     * Obtiene todas las propiedades de una clase.
     * 
     * @param className
     *            Nombre de la clase.
     * @return Propiedades de la clase.
     * @throws ClassNotFoundException
     *             Si ocurre un error.
     * @throws IllegalAccessException
     *             Si ocurre un error.
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> getClassConstants(final String className) throws ClassNotFoundException,
        IllegalAccessException {
        Map<String, Object> constants = new HashMap<String, Object>();
        Class clazz = loadClass(className);

        Field[] fields = clazz.getFields();
        for (int i = 0; i < fields.length; ++i) {
            Field field = fields[i];
            int modifiers = field.getModifiers();
            if (((modifiers & 0x8) != 0) && ((modifiers & 0x10) != 0)) {
                Object value = field.get(null);
                if (value != null) {
                    constants.put(field.getName(), value);
                }
            }
        }
        return constants;
    }

    /**
     * Devuelve el nombre de una clase (quitando el paquete).
     * 
     * @param clazz
     *            Clase de la que queremos saber el nombre.
     * @return Nombre de la clase.
     */
    public static String getClassName(Object clazz) {
        String[] fullName = clazz.getClass().getName().split("\\.");
        return fullName[fullName.length - 1];
    }

    /**
     * Quita el paquete a un nombre de clase completo (se queda con la parte que hay detrás del último ".".
     * 
     * @param className
     *            . Nombre de la clase
     * @return Nombre de la clase sin el paquete.
     */
    public static String removePackage(String className) {
        String[] fullName = className.split("\\.");
        return fullName[fullName.length - 1];
    }

    /**
     * Constructor para evitar instanciaciones.
     */
    private Utils() {
    }

    /**
     * Pone la primera letra de un String a mayúsculas.
     * 
     * @param entrada
     *            String que se quiere procesar.
     * @return String con la primera letra en mayúsculas.
     */
    public static String firstUpper(String entrada) {
        String sufijo, prefijo;

        prefijo = entrada.substring(0, 1);
        prefijo = prefijo.toUpperCase();
        sufijo = entrada.substring(1);

        return prefijo + sufijo;
    }

}
